const includes = require("../utils/arrayApi")
class Player {
  constructor(socket, name) {
    this.socket = socket; //socket对象
    this.name = name;  //玩家昵称
    this.roomId = null; //当前所在房间
    this.state = 0;  // 0代表空闲, 1在游戏中
    this.pipei = false  // 是否在匹配,默认不匹配
    this.firstFlag = false; //是否是第一个出牌的玩家
    this.flag = false  // 是否轮到这个玩家出牌
    this.cardsNumber = 0;  //玩家手中的牌
    this.timer = null;  //定时器
    this.order = 0; //出牌顺序
    this.check = false; //是否过牌
    this.pokers = []; //玩家手里牌
    this.prePlayCards = null; //上一次出过的牌
    this.chuguopai = false; //是否出过牌
    this.integral = 0; //积分
    this.waitGameEnd = false; //等待游戏结束标志
    const _this = this; //玩家自身

    global.playerCount++; //添加在线玩家
    this.init(_this);
  }
  init(_this) {
    this.exit(_this);
  }
  // 清除定时器
  clearTimter() {
    clearInterval(this.timer)
    this.timer = null;
  }
  // 玩家退出游戏
  exit(_this) {
    _this.socket.on('disconnect', function () {
      clearInterval(_this.timer);  //关闭定时器
      global.players = global.players.filter(item => {
        return item.name !== _this.name;
      })
      global.playerCount--;  //减少在线玩家
    })
  }
  // 加入房间
  joinRoom(roomId) {
    this.socket.join(roomId);
    this.roomId = roomId;
    console.log(this.roomId);
  }
  // 开始游戏
  play() {
    // this.socket.emit('play', { code: 0, message: "匹配成功~即将进入游戏界面...." })
    this._socketSuccess("play", `匹配成功~即将进入游戏界面....`, this.roomId)
  }
  // 发牌
  licensing(pokers) {
    pokers.forEach(poker => {
      this.pokers.push(poker); //将管理员发的牌存到自身带的牌中
    })
    this.socket.emit('licensing', { code: 0, message: `玩家：${this.name}`, pokers: this.pokers });
  }
  // 出牌
  playCards() {
    this.socket.on('playCards', data => {
      if(this.flag){
        this.Game.roundCope(this,data);
      } else{
        // this._socketError("playCards", `还没轮到你出牌`)
        this.playCardsError("还没轮到你出牌")
      }
    })
  }
  // 放出的牌
  outCard(data){
    let result = false
    return new Promise((resolve,reject) =>{
      // 第一个出牌的玩家
      if (this.firstFlag) {
        // 首次出牌的玩家不能过牌
        if(data.check){
          // this._socketError("playCards", `首次出牌的玩家不能过牌`)
          this.playCardsError("首次出牌的玩家不能过牌")
          reject(result);       
        }else{
          // 做出牌处理
          this.prePlayCards = data.pokers; //设置当前要出的牌
          this.socket.to(this.roomId).emit('playCards', { code: 0, message: "出牌成功", data: {
            pokers: this.prePlayCards,
            name: this.name
          } })
          // this._socketSuccess("playCardsSelf", "出牌成功", {
          //   pokers: this.prePlayCards,
          //   flag: true
          // });
          this.playCardsSuccess(this.prePlayCards)
          this.firstFlag = false;
          // 返回出过的牌
          resolve(this.prePlayCards)
        }
      }
      // 轮到该玩家出牌
      else if (this.flag) {
        // 判断是否出牌
        // console.log(data,"数据");
        // console.log(Boolean(data),"数据类型");
        if (data && data.check) {
          // ---不出牌直接返回状态
          this.prePlayCards = "check"; //设置当前要出的牌
          this.socket.to(this.roomId).emit('playCards', { code: 0, message: "出牌成功", data: {
            pokers: this.prePlayCards,
            name: this.name
          } })
          this.playCardsSuccess(this.prePlayCards)
          resolve(this.prePlayCards)
        } else {
          // 做出牌处理
          this.compareCards(this.Game.cards, data.pokers)
          .then(res => {
            this.prePlayCards = res;
            this.check = false; //返回出牌状态
            resolve(this.prePlayCards)
          },rej => {
            reject(rej)
          }).catch(err => {
            console.log(err)
          })
          // 返回出过的牌
        }
      } else {
        // this._socketError("playCards", `还没轮到你出牌`)
        this.playCardsError("还没轮到你出牌")
        reject(result);
      }
    })
    
  }
  // 匹配成功,初始化玩家状态
  initPlayState() {
    this.state = 1; //游戏中
    this.pipei = false; //结束匹配
  }
  // 比牌
  compareCards(before, after) {
    let result = false;
    return new Promise((resolve,reject) =>{
      // 判断传过来的牌是否与上家出牌的类型相等，再做处理
      if (before.constructor === after.constructor) {
        // 先处理传过来的牌，如果是单张直接比，多张牌需要遍历再做处理
        // 传过来的牌为对象，是单张
        if (after.constructor === Object) {
          // 先比牌
          if (after.size > before.size) {
            // 可以放
            this.socket.to(this.roomId).emit("playCards", { code: 0, message: `出牌成功`, data: {
              pokers: after,
              name: this.name
            } })
            // this._socketSuccess("playCardsSelf", "出牌成功", {
            //   pokers: after,
            //   flag: true
            // });
            this.playCardsSuccess(after)
            resolve(after);
          } else {
            // 不可以放
            // self.socket.emit("playCards", { code: 0, message: `出牌失败,牌面小于上家`, after })
            // this._socketError("playCards", `出牌失败,牌面小于上家`, after)
            this.playCardsError("出牌失败,牌面小于上家", after)
            reject(result);
          }
          // 传过来的牌为数组，是多张
        } else if (after.constructor === Array) {
          // 判断出牌张数是否与上家相同
          if (after.length != before.length) {
            // self.socket.emit("playCards", { code: 0, message: `出牌失败,出牌张数与上家张数不符合`, after })
            // this._socketError("playCards", `出牌失败,出牌张数与上家张数不符合`, after)
            this.playCardsError("出牌失败,出牌张数与上家张数不符合", after);
            reject(result);
          } else {
            // 判断多张牌的牌面是否相同
            let flag = after.some((item, index, arr) => {
              return item.points === arr[0].points;
            });
            // 牌面相同
            if (flag) {
              // 对比前后出牌的第一张牌，如果大于上一家的牌面，可以出牌
              if (after[0].size > before[0].size) {
                // 可以放
                this.socket.to(this.roomId).emit("playCards", { code: 0, message: `出牌成功`, data: {
                  pokers: after,
                  name: this.name
                } })
                // this._socketSuccess("playCardsSelf", "出牌成功", {
                //   pokers: after,
                //   flag: true
                // });
                this.playCardsSuccess(after)
                resolve(after);
              } else {
                // 不可以放
                // self.socket.emit("playCards", { code: 0, message: `出牌失败,牌面小于上家`, after })
              // this._socketError("playCards", `出牌失败,牌面小于上家`, after)
              this.playCardsError("出牌失败,牌面小于上家", after);
              reject(result);
              }
              // 牌面不相同
            } else {
              // self.socket.emit("playCards", { code: 0, message: `出牌失败,牌面类型不符合出牌规则`, after })
              // this._socketError("playCards", `出牌失败,牌面类型不符合出牌规则`, after)
              this.playCardsError("出牌失败,牌面类型不符合出牌规则", after);
              reject(result);
            }
          }
        }
      } else {
        // self.socket.emit("playCards", { code: 0, message: `出牌失败,牌面与上家不符合类型`, after })
        // this._socketError("playCards", `出牌失败,牌面与上家不符合类型`, after)
        this.playCardsError("出牌失败,牌面与上家不符合类型", after);
        reject(result);
      }
    })
  }
  // 等待对局结束
  awaitGameEnd() {
    this._socketSuccess("awaitGameEnd", "等待对局结束", true)
  }
  // 监听自身牌数和其他玩家牌数
  cardsCount(data) {
      this.socket.emit("cardsCount", { code: 0, message: "玩家牌数", data })
  }
  // 监听系统出牌
  sysPlayCards(cards) {
    // this.socket.emit("sysPlayCards", { code: 0, message: "系统出牌", cards })
    this._socketSuccess("chupai","系统出牌", cards)
  }
  // 监听谁出牌
  chupai(name) {
    // this.socket.emit("chupai", { code: 0, message: "轮到你出牌了", data: null })
    this._socketSuccess("chupai",`轮到${name}出牌了`, { name })
  }
  // 首次出牌发送消息
  firstPlay(){
    this._socketSuccess("firstPlay", "您是首次出牌玩家", { firstPlay: true })
  }
  // 积分广播
  integralMsg(name,integral){
    this._socketSuccess("integralMsg", `${name}玩家拿到了${integral}积分！`, { name, integral })
  }
  // 交互动画广播
  animation(){
    this.socket.on("animation", data => {
      this.socket.to(this.roomId).emit("animation", data);
    })
  }
  // 发送socket成功消息
  _socketSuccess(msg,message,data){
    this.socket.emit(msg, { code: 0, message: message, data: data || null });
  }
  // 发送socket失败消息
  _socketError(msg,message,data){
    this.socket.emit(msg, { code: 1, message: message, data: data || null });
  }
  // 出牌成功触发消息
  playCardsSuccess(pokers){
    // 过牌的情况下不处理，值返回消息
    if(pokers == "check"){
      // 发送消息
      this.check = true; //过牌
      this.socket.emit("playCardsSelf", { code: 0, message: "出牌成功", data: {
        check: true,
        flag: true
      } })
      return
    }
    // 拿到出过的牌的索引
    let indexArr = includes(this.pokers,pokers);
    // 将出过的牌干掉
    indexArr.forEach(i =>{
      this.pokers.splice(i,1);
    })
    // 发送消息
    this.socket.emit("playCardsSelf", { code: 0, message: "出牌成功", data: {
      pokers,
      flag: true
    } })
  }
  // 出牌失败触发消息
  playCardsError(message,data){
    this.socket.emit("playCardsSelf", { code: 1, message: message, data: {
      flag: false,
      data: data || null
    } })
  }

}

module.exports = Player;